package robocup.component.worldmodel;

import java.util.EnumMap;

import robocup.component.geometry.Vektor;
import robocup.component.infotypes.Info;
import robocup.component.worldobjects.Player;

/**
 * This class stores knowledge already calculated by the player in the current
 * decision process. Should be used for results of complex methods.
 * 
 * By now this class isn't used muched...
 * 
 * TODO cache more values
 */
public class ShortTermMemory {

  // the unknown values
  public final static Boolean BOOLEAN_UNKNOWN = null;

  public final static Double  DOUBLE_UNKNOWN  = null;

  public final static Vektor  VEKTOR_UNKNOWN  = null;

  public final static Player  PLAYER_UNKNOWN  = null;

  // boolean - Values
  public enum BOOLEANS {
    DUMMY
  }


  // double - values
  public enum DOUBLES {
    TEAM_OFFSIDE_Y,
    OPPONENT_OFFSIDE_Y
  }


  // Vektor - values
  public enum VEKTORS {
    MY_NEXT_POSITION
  }


	// Player - values
	public enum PLAYERS {
		PREDICTED_SELF, 
    FASTEST_ENEMY_TO_BALL, 
    FASTEST_TEAMMATE_TO_BALL
	}


  // map containing booleans
  public EnumMap<BOOLEANS, Boolean> booleanMap = new EnumMap<BOOLEANS, Boolean>(
                                                   BOOLEANS.class);

  // map containing double values
  public EnumMap<DOUBLES, Double>   doubleMap  = new EnumMap<DOUBLES, Double>(
                                                   DOUBLES.class);

  // map containing Vektors
  public EnumMap<VEKTORS, Vektor>   vektorMap  = new EnumMap<VEKTORS, Vektor>(
                                                   VEKTORS.class);

  // map containing Players
  public EnumMap<PLAYERS, Player>   playerMap  = new EnumMap<PLAYERS, Player>(
                                                   PLAYERS.class);

  /**
   * Constructor - a short-term memory stores information, which is used more
   * often in one cycle, in order to save computing effort (more complex
   * information is stored in situations, e.g. the interception point).
   */
  public ShortTermMemory() {

    this.resetAll(Info.TYPE_SENSE);
  }

  /**
   * Resets the Memory.
   * @param infotyp 
   * 
   */
  public void resetAll(final int infotyp) {

    if (infotyp == Info.TYPE_SENSE) {
      // collisions remain for whole cycle
      for (final BOOLEANS b : BOOLEANS.values()) {
        this.booleanMap.put(b, ShortTermMemory.BOOLEAN_UNKNOWN);
      }
    }
    for (final DOUBLES d : DOUBLES.values()) {
      this.doubleMap.put(d, ShortTermMemory.DOUBLE_UNKNOWN);
    }
    for (final VEKTORS v : VEKTORS.values()) {
      this.vektorMap.put(v, ShortTermMemory.VEKTOR_UNKNOWN);
    }
    for (final PLAYERS p : PLAYERS.values()) {
      this.playerMap.put(p, ShortTermMemory.PLAYER_UNKNOWN);
    }
  }

  /**
   * Sets the boolean value b for dEnum.
   * 
   * @param bEnum -
   *          key
   * @param b -
   *          value
   */
  public void set(final BOOLEANS bEnum,
      final boolean b) {

    this.booleanMap.put(bEnum, Boolean.valueOf(b));
  }

  /**
   * Sets the double value d for dEnum.
   * 
   * @param dEnum -
   *          key
   * @param d -
   *          value
   */
  public void set(final DOUBLES dEnum,
      final double d) {

    this.doubleMap.put(dEnum, Double.valueOf(d));
  }

  /**
   * Sets the Vektor v for vEnum.
   * 
   * @param vEnum -
   *          key
   * @param v -
   *          Vektor
   */
  public void set(final VEKTORS vEnum,
      final Vektor v) {

    this.vektorMap.put(vEnum, v);
  }

  /**
   * Sets the Player p for pEnum.
   * 
   * @param pEnum -
   *          key
   * @param p -
   *          Player to set
   */
  public void set(final PLAYERS pEnum,
      final Player p) {

    this.playerMap.put(pEnum, p);
  }

  /**
   * Returns the value for a given key (bEnum). (Bool Version)
   * 
   * @param bEnum -
   *          key
   * @return the Boolean belonging to the key (null if unknown)
   */
  public Boolean get(final BOOLEANS bEnum) {

    return this.booleanMap.get(bEnum);
  }

  /**
   * Returns the value for a given key (dEnum). (Double Version)
   * 
   * @param dEnum -
   *          key
   * @return the Double value belonging to the key (null for unknown)
   */
  public Double get(final DOUBLES dEnum) {

    if (this.doubleMap.get(dEnum) == ShortTermMemory.DOUBLE_UNKNOWN) {
      return ShortTermMemory.DOUBLE_UNKNOWN;
    }
    return this.doubleMap.get(dEnum);
  }


  /**
   * Returns the Vektor for a given key (vEnum). (Vektor Version)
   * 
   * @param vEnum -
   *          key
   * @return the Vektor belonging to the key
   */
  public Vektor get(final VEKTORS vEnum) {
    if (this.vektorMap.get(vEnum) == ShortTermMemory.VEKTOR_UNKNOWN) {
      return ShortTermMemory.VEKTOR_UNKNOWN;
    }
    return this.vektorMap.get(vEnum);
  }

  /**
   * Returns the Vektor for a given key (vEnum). (Vektor Version)
   * 
   * @param pEnum -
   *            key
   * @return the Vektor belonging to the key
   */
  public Player get(final PLAYERS pEnum) {

    if (this.playerMap.get(pEnum) == ShortTermMemory.PLAYER_UNKNOWN) {
      return ShortTermMemory.PLAYER_UNKNOWN;
    }
    return this.playerMap.get(pEnum);
  }

}
